package com.qut.graduate.busrtquery.utils.net;

import com.qut.graduate.busrtquery.BRTQCache;
import com.qut.graduate.busrtquery.BRTQConstant;
import com.qut.graduate.busrtquery.bean.User;
import com.qut.graduate.busrtquery.greendao.bean.BusLineCollect;
import com.qut.graduate.busrtquery.greendao.bean.StationInfoCollect;
import com.qut.graduate.busrtquery.greendao.controller.DBController;
import com.qut.graduate.busrtquery.utils.common.LogUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.bmob.v3.BmobBatch;
import cn.bmob.v3.BmobObject;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.datatype.BatchResult;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.FindListener;
import cn.bmob.v3.listener.QueryListListener;

/**
 * @Author WLL
 * @Time: 2019/5/14 10:56
 */
public class BmobCollectUtils {

    /**
     * 根据bmob后端云存储的收藏线路更新本地的内存和数据库中的收藏线路数据
     * @param user
     */
    public static void updateLocalBusLinesFromBmob(final User user){
        BmobQuery<BusLineCollect> categoryBmobQuery = new BmobQuery<>();
        categoryBmobQuery.addWhereEqualTo("userId", user.getObjectId());
        categoryBmobQuery.findObjects(new FindListener<BusLineCollect>() {
            @Override
            public void done(List<BusLineCollect> object, BmobException e) {
                if (e == null) {
                    LogUtils.d("bmob updateLocalBusLinesFromBmob 查询BusLineCollect成功：" + object.size());
                    BRTQCache.getInstance().getBusLineCollectList().addAll(object);
                    DBController.getInstance().insertInTxTable(BRTQConstant.DB_TABLE_TYPE_BUS_LINE_COLLECT,object);
                    LogUtils.d("bmob 登录后更新后本地数据 getBusLineCollectList:" + BRTQCache.getInstance().getBusLineCollectList());
                } else {
                    LogUtils.d("bmob updateLocalBusLinesFromBmob 查询BusLineCollect失败：" + e.toString());
                }
            }
        });
    }

    /**
     * 根据bmob后端云存储的收藏站点更新本地的内存和数据库中的收藏站点数据
     * @param user
     */
    public static void updateLocalStationInfosFromBmob(final User user){
        BmobQuery<StationInfoCollect> categoryBmobQuery = new BmobQuery<>();
        categoryBmobQuery.addWhereEqualTo("userId", user.getObjectId());
        categoryBmobQuery.findObjects(new FindListener<StationInfoCollect>() {
            @Override
            public void done(List<StationInfoCollect> object, BmobException e) {
                if (e == null) {
                    LogUtils.d("bmob updateLocalStationInfosFromBmob 查询StationInfoCollect成功：" + object.size());
                    BRTQCache.getInstance().getStationInfoCollectList().addAll(object);
                    DBController.getInstance().insertInTxTable(BRTQConstant.DB_TABLE_TYPE_STATION_INFO_COLLECT,object);
                    LogUtils.d("bmob 登录后更新后本地数据 getStationInfoCollectList:" + BRTQCache.getInstance().getStationInfoCollectList());
                } else {
                    LogUtils.d("bmob updateLocalStationInfosFromBmob 查询StationInfoCollect失败：" + e.toString());
                }
            }
        });
    }

    /**
     * 更新当前用户bmob后端云的收藏线路，删除本地当前用户内存和数据库中的收藏线路
     *
     * @return
     */
    public static List<BusLineCollect> updateBmobBusLines(final User user) {
        final ArrayList[] busLineCollects = {new ArrayList()};
        BmobQuery<BusLineCollect> categoryBmobQuery = new BmobQuery<>();
        categoryBmobQuery.addWhereEqualTo("userId", user.getObjectId());
        categoryBmobQuery.findObjects(new FindListener<BusLineCollect>() {
            @Override
            public void done(List<BusLineCollect> object, BmobException e) {
                if (e == null) {
                    busLineCollects[0] = (ArrayList) object;
                    LogUtils.d("bmob updateBmobBusLines 查询BusLineCollect成功：" + object.size());
                    List<BusLineCollect> busLineCollects = BRTQCache.getInstance().getBusLineCollectList();
                    List<BusLineCollect> localSubBusLines = BmobCollectUtils.getDiffBusLineFromLocal(busLineCollects, object);
                    List<BusLineCollect> bmobSubBusLines = BmobCollectUtils.getDiffBusLineFromBmob(busLineCollects, object);
                    LogUtils.d("bmob updateBmobBusLines localSubBusLines.size：" + localSubBusLines.size()
                            + "  bmobSubBusLines.size：" + bmobSubBusLines.size());
                    saveBusLinesToBmob(localSubBusLines,user);
                    deleteBusLinesFromBmob(bmobSubBusLines);
                    BRTQCache.getInstance().getBusLineCollectList().clear();
                    DBController.getInstance().deleteNotThisUserCollect(BRTQConstant.DB_TABLE_TYPE_BUS_LINE_COLLECT,user.getObjectId());
                } else {
                    LogUtils.d("bmob updateBmobBusLines 查询BusLineCollect失败：" + e.toString());
                }
            }
        });
        return busLineCollects[0];
    }

    /**
     * 更新当前用户bmob后端云的收藏站点，删除本地当前用户内存和数据库中的收藏站点
     *
     * @return
     */
    public static List<StationInfoCollect> updateBmobStationInfos(final User user) {
        final ArrayList[] stationInfoCollects = {new ArrayList()};
        BmobQuery<StationInfoCollect> categoryBmobQuery = new BmobQuery<>();
        categoryBmobQuery.addWhereEqualTo("userId", user.getObjectId());
        categoryBmobQuery.findObjects(new FindListener<StationInfoCollect>() {
            @Override
            public void done(List<StationInfoCollect> object, BmobException e) {
                if (e == null) {
                    stationInfoCollects[0] = (ArrayList) object;
                    LogUtils.d("bmob updateBmobStationInfos 查询StationInfoCollect成功：" + object.size());
                    List<StationInfoCollect> stationInfoCollects = BRTQCache.getInstance().getStationInfoCollectList();
                    List<StationInfoCollect> localSubStationInfos = BmobCollectUtils.getDiffStationInfoFromLocal(stationInfoCollects, object);
                    List<StationInfoCollect> bmobSubStationInfos = BmobCollectUtils.getDiffStationInfoFromBmob(stationInfoCollects, object);
                    LogUtils.d("bmob updateBmobStationInfos localSubStationInfos.size：" + localSubStationInfos.size()
                            + "  bmobSubStationInfos.size：" + bmobSubStationInfos.size());
                    saveStationInfosToBmob(localSubStationInfos,user);
                    deleteStationInfosFromBmob(bmobSubStationInfos);
                    BRTQCache.getInstance().getStationInfoCollectList().clear();
                    DBController.getInstance().deleteNotThisUserCollect(BRTQConstant.DB_TABLE_TYPE_STATION_INFO_COLLECT,user.getObjectId());
                } else {
                    LogUtils.d("bmob updateBmobStationInfos 查询StationInfoCollect失败：" + e.toString());
                }
            }
        });
        return stationInfoCollects[0];
    }

    /**
     * 往bomb上新增多条线路收藏数据
     */
    public static List<BatchResult> saveBusLinesToBmob(List<BusLineCollect> busLineCollectList,User user) {
        LogUtils.d("bmob saveBusLinesToBmob user.getObjectId()" + user.getObjectId());
        List<BmobObject> categories = new ArrayList<>();
        for (int i = 0; i < busLineCollectList.size(); i++) {
            BusLineCollect busLineCollect = new BusLineCollect();
            busLineCollect.setId(busLineCollectList.get(i).getId());
            busLineCollect.setRid(busLineCollectList.get(i).getRid());
            busLineCollect.setName(busLineCollectList.get(i).getName());
            busLineCollect.setLine(busLineCollectList.get(i).getLine());
            busLineCollect.setType(busLineCollectList.get(i).getType());
            busLineCollect.setTime(busLineCollectList.get(i).getTime());
            busLineCollect.setUserId(user.getObjectId());
            categories.add(busLineCollect);
        }
        final List<BatchResult> mResults = new ArrayList<>();
        new BmobBatch().insertBatch(categories).doBatch(new QueryListListener<BatchResult>() {
            @Override
            public void done(List<BatchResult> results, BmobException e) {
                if (e == null) {
                    for (int i = 0; i < results.size(); i++) {
                        BatchResult result = results.get(i);
                        BmobException ex = result.getError();
                        if (ex == null) {
                            LogUtils.d("bmob saveBusLinesToBmob 第" + (i+1) + "个数据批量添加成功："
                                    + result.getCreatedAt() + " , " + result.getObjectId());
                        } else {
                            LogUtils.d("bmob saveBusLinesToBmob 第" + (i+1) + "个数据批量添加失败："
                                    + ex.getMessage() + ", " + ex.getErrorCode());
                        }
                    }
                    mResults.addAll(results);
                } else {
                    LogUtils.d("bmob saveBusLinesToBmob 失败：" + e.getMessage() + "," + e.getErrorCode());
                }
            }
        });
        return mResults;
    }

    /**
     * 往bomb上新增多条站点收藏数据
     */
    public static List<BatchResult> saveStationInfosToBmob(List<StationInfoCollect> stationInfoCollectList,User user) {
        LogUtils.d("bmob saveStationInfosToBmob user.getObjectId()" + user.getObjectId());
        List<BmobObject> categories = new ArrayList<>();
        for (int i = 0; i < stationInfoCollectList.size(); i++) {
            StationInfoCollect stationInfoCollect = new StationInfoCollect();
            stationInfoCollect.setId(stationInfoCollectList.get(i).getId());
            stationInfoCollect.setName(stationInfoCollectList.get(i).getName());
            stationInfoCollect.setAddress(stationInfoCollectList.get(i).getAddress());
            stationInfoCollect.setCity(stationInfoCollectList.get(i).getCity());
            stationInfoCollect.setLatitude(stationInfoCollectList.get(i).getLatitude());
            stationInfoCollect.setLongitude(stationInfoCollectList.get(i).getLongitude());
            stationInfoCollect.setTime(stationInfoCollectList.get(i).getTime());
            stationInfoCollect.setUserId(user.getObjectId());
            categories.add(stationInfoCollect);
        }
        final List<BatchResult> mResults = new ArrayList<>();
        new BmobBatch().insertBatch(categories).doBatch(new QueryListListener<BatchResult>() {
            @Override
            public void done(List<BatchResult> results, BmobException e) {
                if (e == null) {
                    for (int i = 0; i < results.size(); i++) {
                        BatchResult result = results.get(i);
                        BmobException ex = result.getError();
                        if (ex == null) {
                            LogUtils.d("bmob saveStationInfosToBmob 第" + (i+1) + "个数据批量添加成功："
                                    + result.getCreatedAt() + ", " + result.getObjectId());
                        } else {
                            LogUtils.d("bmob saveStationInfosToBmob 第" + (i+1) + "个数据批量添加失败："
                                    + ex.getMessage() + ", " + ex.getErrorCode());
                        }
                    }
                    mResults.addAll(results);
                } else {
                    LogUtils.d("bmob saveStationInfosToBmob 失败：" + e.getMessage() + "," + e.getErrorCode());
                }
            }
        });
        return mResults;
    }

    /**
     * 从bomb后端云批量删除收藏的线路
     */
    public static void deleteBusLinesFromBmob(List<BusLineCollect> busLineCollectList) {
        LogUtils.d("bmob deleteBusLinesFromBmob busLineCollectList:" + busLineCollectList);
        List<BmobObject> categories = new ArrayList<>();
        for (int i = 0; i < busLineCollectList.size(); i++) {
//            BusLineCollect busLineCollect = new BusLineCollect();
//            busLineCollect.setObjectId(busLineCollectList.get(i).getObjectId());
            categories.add(busLineCollectList.get(i));
        }
        new BmobBatch().deleteBatch(categories).doBatch(new QueryListListener<BatchResult>() {
            @Override
            public void done(List<BatchResult> results, BmobException e) {
                if (e == null) {
                    for (int i = 0; i < results.size(); i++) {
                        BatchResult result = results.get(i);
                        BmobException ex = result.getError();
                        if (ex == null) {
                            LogUtils.d("bmob deleteBusLinesFromBmob  第" + (i+1) + "个数据批量删除成功："
                                    + result.getCreatedAt() + ", " + result.getObjectId());
                        } else {
                            LogUtils.d( "bmob deleteBusLinesFromBmob  第" + (i+1) + "个数据批量删除失败："
                                    + ex.getMessage() + ", " + ex.getErrorCode());
                        }
                    }
                } else {
                    LogUtils.d( "bmob deleteBusLinesFromBmob  失败：" + e.getMessage() + "," + e.getErrorCode());
                }
            }
        });
    }

    /**
     * 从bomb后端云批量删除收藏的站点
     */
    public static void deleteStationInfosFromBmob(List<StationInfoCollect> stationInfoCollectList) {
        LogUtils.d("bmob deleteStationInfosFromBmob stationInfoCollectList:" + stationInfoCollectList);
        List<BmobObject> categories = new ArrayList<>();
        for (int i = 0; i < stationInfoCollectList.size(); i++) {
//            StationInfoCollect stationInfoCollect = new StationInfoCollect();
//            stationInfoCollect.setObjectId(stationInfoCollectList.get(i).getObjectId());
            categories.add(stationInfoCollectList.get(i));
        }
        categories.addAll(stationInfoCollectList);
        new BmobBatch().deleteBatch(categories).doBatch(new QueryListListener<BatchResult>() {
            @Override
            public void done(List<BatchResult> results, BmobException e) {
                if (e == null) {
                    for (int i = 0; i < results.size(); i++) {
                        BatchResult result = results.get(i);
                        BmobException ex = result.getError();
                        if (ex == null) {
                            LogUtils.d("bmob deleteStationInfosFromBmob  第" + (i+1) + "个数据批量删除成功："
                                    + result.getCreatedAt() + ", " + result.getObjectId());
                        } else {
                            LogUtils.d( "bmob deleteStationInfosFromBmob  第" + (i+1) + "个数据批量删除失败："
                                    + ex.getMessage() + ", " + ex.getErrorCode());
                        }
                    }
                } else {
                    LogUtils.d( "bmob deleteStationInfosFromBmob  失败：" + e.getMessage() + "," + e.getErrorCode());
                }
            }
        });
    }

    /**
     * 截取本地线路list中比bmob后端云上的收藏线路list中多出的不同元素
     *
     * @param localBusLines
     * @param bmobBusLines
     * @return
     */
    public static List<BusLineCollect> getDiffBusLineFromLocal(
            List<BusLineCollect> localBusLines, List<BusLineCollect> bmobBusLines) {

        Map<BusLineCollect, Integer> map = new HashMap<>(localBusLines.size() + bmobBusLines.size());
        List<BusLineCollect> diff = new ArrayList<>();
        for (BusLineCollect busLineCollect : localBusLines) {
            map.put(busLineCollect, 1);
        }
        for (BusLineCollect busLineCollect : bmobBusLines) {
            if (map.get(busLineCollect) != null) {
                map.put(busLineCollect, 2);
                continue;
            }
            // diff.add(busLineCollect);
        }
        for (Map.Entry<BusLineCollect, Integer> entry : map.entrySet()) {
            if (entry.getValue() == 1) {
                diff.add(entry.getKey());
            }
        }
        return diff;
    }

    /**
     * 截取本地线路list中比bmob后端云上的收藏线路list中少的不同元素
     *
     * @param localBusLines
     * @param bmobBusLines
     * @return
     */
    public static List<BusLineCollect> getDiffBusLineFromBmob(
            List<BusLineCollect> localBusLines, List<BusLineCollect> bmobBusLines) {

        Map<BusLineCollect, Integer> map = new HashMap<>(localBusLines.size() + bmobBusLines.size());
        List<BusLineCollect> diff = new ArrayList<>();
        for (BusLineCollect busLineCollect : localBusLines) {
            map.put(busLineCollect, 1);
        }
        for (BusLineCollect busLineCollect : bmobBusLines) {
            if (map.get(busLineCollect) != null) {
                map.put(busLineCollect, 2);
                continue;
            }
            diff.add(busLineCollect);
        }
        return diff;
    }

    /**
     * 截取本地站点list中比bmob后端云上的收藏站点list中多的不同元素
     *
     * @param localStationInfos
     * @param bmobStationInfos
     * @return
     */
    public static List<StationInfoCollect> getDiffStationInfoFromLocal(
            List<StationInfoCollect> localStationInfos, List<StationInfoCollect> bmobStationInfos) {

        Map<StationInfoCollect, Integer> map = new HashMap<>(localStationInfos.size() + bmobStationInfos.size());
        List<StationInfoCollect> diff = new ArrayList<>();
        for (StationInfoCollect stationInfoCollect : localStationInfos) {
            map.put(stationInfoCollect, 1);
        }
        for (StationInfoCollect stationInfoCollect : bmobStationInfos) {
            if (map.get(stationInfoCollect) != null) {
                map.put(stationInfoCollect, 2);
                continue;
            }
        }
        for (Map.Entry<StationInfoCollect, Integer> entry : map.entrySet()) {
            if (entry.getValue() == 1) {
                diff.add(entry.getKey());
            }
        }
        return diff;
    }

    /**
     * 截取本地站点list中比bmob后端云上的收藏站点list中少的不同元素
     *
     * @param localStationInfos
     * @param bmobStationInfos
     * @return
     */
    public static List<StationInfoCollect> getDiffStationInfoFromBmob(
            List<StationInfoCollect> localStationInfos, List<StationInfoCollect> bmobStationInfos) {

        Map<StationInfoCollect, Integer> map = new HashMap<>(localStationInfos.size() + bmobStationInfos.size());
        List<StationInfoCollect> diff = new ArrayList<>();
        for (StationInfoCollect stationInfoCollect : localStationInfos) {
            map.put(stationInfoCollect, 1);
        }
        for (StationInfoCollect stationInfoCollect : bmobStationInfos) {
            if (map.get(stationInfoCollect) != null) {
                map.put(stationInfoCollect, 2);
                continue;
            }
            diff.add(stationInfoCollect);
        }
        return diff;
    }

}
